import axios from 'axios'
import type { ApiResponse } from '@/types'
import { ElMessage } from 'element-plus'

// 创建axios实例
const request = axios.create({
  baseURL: '/api',
  timeout: 30000, // 增加超时时间到30秒
  // 添加重试配置
  retry: 3,
  retryDelay: 1000
})

// 扩展axios配置类型，添加自定义选项
declare module 'axios' {
  interface AxiosRequestConfig {
    // 是否跳过重定向处理
    skipRedirectHandling?: boolean;
  }
}

// 请求拦截器
request.interceptors.request.use(
  (config) => {
    const token = localStorage.getItem('token')
    if (token) {
      // Sa-Token默认从satoken请求头中获取token
      config.headers['satoken'] = token
      // 也可以使用Authorization头
      config.headers['Authorization'] = `Bearer ${token}`
    }
    return config
  },
  (error) => {
    return Promise.reject(error)
  }
)

// 响应拦截器
request.interceptors.response.use(
  (response) => {
    // 根据HTTP状态码进行更完整的判断
    const status = response.status
    
    if (status >= 200 && status < 300) {
      // 2xx: 成功状态码
      return response.data
    } else if (status >= 300 && status < 400) {
      // 3xx: 重定向状态码
      // 通常axios会自动处理重定向，但如果到这里说明需要手动处理
      console.warn(`重定向响应 (${status}):`, response)
      return response.data
    } else {
      // 4xx, 5xx: 错误状态码
      // 通常不会到这里，因为axios会将4xx,5xx作为错误处理
      const errorMsg = response.data?.message || `请求失败 (${status})`
      return Promise.reject(new Error(errorMsg))
    }
  },
  (error) => {
    let errorMessage = '网络错误'
    
    if (error.response) {
      // 服务器响应了错误状态码
      const status = error.response.status
      const data = error.response.data
      
      switch (status) {
        case 300:
        case 301:
        case 302:
        case 303:
        case 304:
        case 307:
        case 308:
          // 重定向相关错误（通常axios会自动处理，但某些情况下可能会到这里）
          errorMessage = '页面重定向错误'
          console.warn('重定向错误:', error.response)
          break
        case 400:
          errorMessage = data?.message || '请求参数错误'
          break
        case 401:
          errorMessage = data?.message || '登录已过期，请重新登录'
          break
        case 403:
          errorMessage = data?.message || '没有权限访问该资源'
          break
        case 404:
          errorMessage = data?.message || '请求的资源不存在'
          break
        case 405:
          errorMessage = '请求方法不允许'
          break
        case 406:
          errorMessage = '请求格式不可接受'
          break
        case 408:
          errorMessage = '请求超时'
          break
        case 409:
          errorMessage = '请求冲突'
          break
        case 410:
          errorMessage = '请求的资源已被删除'
          break
        case 413:
          errorMessage = '请求实体过大'
          break
        case 414:
          errorMessage = '请求URI过长'
          break
        case 415:
          errorMessage = '不支持的媒体类型'
          break
        case 422:
          errorMessage = data?.message || '请求参数验证失败'
          break
        case 429:
          errorMessage = '请求过于频繁，请稍后再试'
          break
        case 500:
          errorMessage = data?.message || '服务器内部错误'
          break
        case 501:
          errorMessage = '服务器不支持该功能'
          break
        case 502:
          errorMessage = '网关错误'
          break
        case 503:
          errorMessage = '服务暂时不可用'
          break
        case 504:
          errorMessage = '网关超时'
          break
        case 505:
          errorMessage = 'HTTP版本不支持'
          break
        default:
          errorMessage = data?.message || `请求失败 (${status})`
      }
    } else if (error.request) {
      // 请求已发出但没有收到响应
      if (error.code === 'ECONNABORTED') {
        errorMessage = '请求超时，请重试'
      } else if (error.code === 'ERR_NETWORK') {
        errorMessage = '网络连接失败，请检查网络'
      } else if (error.code === 'ERR_CANCELED') {
        errorMessage = '请求被取消'
        // 请求取消通常不需要显示错误消息
        return Promise.reject(error)
      } else {
        errorMessage = '网络连接超时，请检查网络'
      }
    } else {
      // 请求配置出错
      errorMessage = error.message || '请求配置错误'
    }
    
    return Promise.reject(error)
  }
)

// 创建一个包装函数来处理响应数据，响应拦截器已经返回了data，这里直接返回
const apiRequest = {
  get: <T = any>(url: string, config?: any): Promise<T> => {
    return request.get(url, config)
  },
  post: <T = any>(url: string, data?: any, config?: any): Promise<T> => {
    return request.post(url, data, config)
  }
}

export default apiRequest